# encoding: utf-8
# @File  : test05.py
# @Author: wu shaofan
# @Date  :  2024/02/16
# @Desc : 封装京东滑动块（封装版）
import base64
import os
import time

import cv2
import pyautogui
from selenium.webdriver.support.wait import WebDriverWait

import conftest
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium import webdriver


class SlideBlock:
    def __init__(self):
        chrome_driver_path = conftest.BASE_DIR + '/tool/chromedriver.exe'
        # 创建 ChromeOptions 对象
        options = Options()
        options.add_experimental_option("excludeSwitches", ["enable-logging"])
        # 创建 Chrome WebDriver 服务
        service = Service(chrome_driver_path)
        # 创建 Chrome WebDriver 实例
        self.driver = webdriver.Chrome(service=service, options=options)
        # 窗口最大化
        self.driver.maximize_window()

    def login(self, username, password):
        """
        京东登录
        :param username: 用户名
        :param password: 密码
        :return:
        """
        url = "https://passport.jd.com/uc/login"
        self.driver.get(url)
        self.driver.find_element("id", "loginname").send_keys(username)
        self.driver.find_element("id", "nloginpwd").send_keys(password)
        self.driver.find_element("id", "loginsubmit").click()

    def get_image(self):
        """
        获取图片
        :return:
        """
        # 保存获取到的图片
        loc = ("css selector", 'div.JDJRV-bigimg>img')
        big_url = WebDriverWait(self.driver, timeout=3, poll_frequency=0.5).until(lambda x: x.find_element(*loc)).get_attribute('src')
        small_url = self.driver.find_element("css selector", 'div.JDJRV-smallimg>img').get_attribute('src')

        # 利用split的来进行数据的分割也可以
        big_base64_str = big_url.split(',')[-1]
        small_base64_str = small_url.split(',')[-1]

        # 图片的二进制的数据
        big_binary_content = base64.b64decode(big_base64_str)
        small_binary_content = base64.b64decode(small_base64_str)

        # 判断文件夹是否存在不存在则创建'
        os.makedirs('./image/', exist_ok=True)
        #  保存图片
        with open('./image/big.png', mode='wb') as f:
            f.write(big_binary_content)
        with open('./image/small.png', mode='wb') as f:
            f.write(small_binary_content)

    def FindPic(self, target='big.png', template='small.png'):
        target_rgb = cv2.imread(target)
        target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_RGB2GRAY)
        template_rgb = cv2.imread(template, 0)
        res = cv2.matchTemplate(target_gray, template_rgb, cv2.TM_CCOEFF_NORMED)
        value = cv2.minMaxLoc(res)
        #print(value)
        return value[2][0]

    def get_distance(self):
        a = self.FindPic('./image/big.png', './image/small.png')
        print("本地图片需要滑动的距离：{}".format(a))

        '''换算距离'''
        distance01 = a * 243 // 360
        print("seleium库相对于网页需要滑动的距离：{}".format(distance01))

        distance = a * 243 * 1.99 // 360
        print("pyautogui库相对于窗口需要滑动的距离：{}".format(distance))

        return distance

    def get_move(self, distance):
        '''
        :param distance: 小图在大图中缺口位置
        :return:
        '''
        # 获取小滑块的位置
        lo = self.driver.find_element("css selector", 'div.JDJRV-smallimg>img').location

        x = lo['x'] * 1.99 + 17
        y = lo['y'] * 1.99 + 160 + 17 + 80

        #  定位鼠标到指定小滑块中心点位置，然后按下
        pyautogui.mouseDown(x, y)
        #  滑过头
        pyautogui.moveTo(x + distance + 20, y + 10, duration=0.3)
        #  滑回来
        pyautogui.moveTo(x + distance - 10, y - 5, duration=0.3)
        # 滑到指定位置
        pyautogui.moveTo(x + distance, y, duration=0.3)
        # 松开鼠标
        pyautogui.mouseUp()
        time.sleep(2)

    def fail_run(self):
            '''失败重试'''
            # 当验证码大小为0 时候就是破解成功了，就不用重试了
            while True:
                self.get_image()
                distance = self.get_distance()
                self.get_move(distance)
                loc = ("css selector", 'div.JDJRV-bigimg>img')
                size = WebDriverWait(self.driver, timeout=3, poll_frequency=0.5).until(lambda x: x.find_element(*loc)).size
                if size.get('width') < 1:
                    break
            # 成功后关闭浏览器
            self.driver.quit()
            print('验证成功')


if __name__ == '__main__':
    obj = SlideBlock()
    obj.login('18312345678', '123456')
    obj.fail_run()
